﻿using System;
using System.IO;
using log4net;
using log4net.Appender;
using log4net.Repository.Hierarchy;
using LogLibrary.Entity;
using LogLibrary.Interface;

namespace LogLibrary.Implementation
{
    internal sealed class LogService : ILogService
    {
        readonly ILog _logger;

        public LogService(string logConfigurationFileName)
        {
            var log4NetConfigDirectory = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
            var log4NetConfigFilePath = Path.Combine(log4NetConfigDirectory, logConfigurationFileName);
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFilePath));
        }

        public LogService(Type logClass)
        {
            try
            {
                if (LogConnectionInfo.SqlConnectionString == string.Empty)
                    throw new Exception("SQL Connection string is not provided to connect with database. Please check.");

                //if (LogConnectionInfo.LogFileLocation == string.Empty)
                //    throw new Exception("Log file location string is not provided. Please check.");

                if (_logger == null)
                {
                    //var log4NetConfigDirectory = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
                    //var log4NetConfigFilePath = Path.Combine( log4NetConfigDirectory , "LogConfiguration.config" );
                    //var log4NetConfigFilePath = Path.Combine(@"..\..\", "LogConfiguration.config");

                    var log4NetConfigDirectory = Environment.CurrentDirectory;
                    var log4NetConfigFilePath = Path.Combine(log4NetConfigDirectory, "LogConfiguration.config");
                 
                    SetUpAppender(LogConnectionInfo.SqlConnectionString, log4NetConfigFilePath);
                    _logger = LogManager.GetLogger(logClass);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void SetUpAppender(string sqlConnectionString, string logConfig)
        {
            var hier = LogManager.GetRepository() as Hierarchy;
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(logConfig));
            if (hier != null)
            {
                var appenders = hier.GetAppenders();
                foreach (var appender in appenders)
                {
                    if (appender.Name == "CustomEFAppender")
                    {
                        ((CustomEFAppender)appender).ConnectionString = sqlConnectionString;
                        ((CustomEFAppender)appender).ActivateOptions();
                    }
                    else if (appender.Name == "RollingFileAppender")
                    {
                        if (!string.IsNullOrEmpty(LogConnectionInfo.LogFileLocation))
                        {
                            ((RollingFileAppender)appender).File = LogConnectionInfo.LogFileLocation;
                        }
                        ((RollingFileAppender)appender).ActivateOptions();
                    }
                }
            }
        }

        #region "Implementation ILogService"

        public void Fatal(string errorMessage)
        {
            if (_logger.IsFatalEnabled)
                _logger.Fatal(errorMessage);
        }

        public void Error(string errorMessage)
        {
            if (_logger.IsErrorEnabled)
                _logger.Error(errorMessage);
        }

        public void Warn(string message)
        {
            if (_logger.IsWarnEnabled)
                _logger.Warn(message);
        }

        public void Info(string message)
        {
            if (_logger.IsInfoEnabled)
                _logger.Info(message);
        }

        public void Debug(string message)
        {
            if (_logger.IsDebugEnabled)
                _logger.Debug(message);
        }

        public void Fatal(Exception exception, string errorMessage)
        {
            if (_logger.IsFatalEnabled)
                _logger.Fatal(errorMessage, exception);
        }

        public void Error(Exception exception, string errorMessage)
        {
            if (_logger.IsErrorEnabled)
                _logger.Error(errorMessage, exception);
        }

        public void Warn(Exception exception, string errorMessage)
        {
            if (_logger.IsWarnEnabled)
                _logger.Warn(errorMessage, exception);
        }

        public void Info(Exception exception, string errorMessage)
        {
            if (_logger.IsInfoEnabled)
                _logger.Info(errorMessage, exception);
        }

        public void Debug(Exception exception, string errorMessage)
        {
            if (_logger.IsDebugEnabled)
                _logger.Debug(errorMessage, exception);
        }

        public void Fatal(LogServiceInformation logInfo)
        {
            if (_logger.IsFatalEnabled)
            {
                _logger.Fatal(logInfo.CustomErrorMessage, logInfo.Exception);
            }
        }

        public void Error(LogServiceInformation logInfo)
        {
            if (_logger.IsErrorEnabled)
            {
                _logger.Error(logInfo.CustomErrorMessage, logInfo.Exception);
            }
        }

        public void Warn(LogServiceInformation logInfo)
        {
            if (_logger.IsWarnEnabled)
            {
                _logger.Warn(logInfo.CustomErrorMessage, logInfo.Exception);
            }
        }

        public void Info(LogServiceInformation logInfo)
        {
            if (_logger.IsInfoEnabled)
            {
                _logger.Info(logInfo.CustomErrorMessage, logInfo.Exception);
            }
        }

        public void Debug(LogServiceInformation logInfo)
        {
            if (_logger.IsDebugEnabled)
            {
                _logger.Debug(logInfo.CustomErrorMessage, logInfo.Exception);
            }
        }

        #endregion
    }
}
